Silverlight
gives you the ability to draw shapes and colors on the surface of the
phone itself. While you might not imagine doing much actual drawing, it
is important for you to understand how creating a design with the
drawing primitives is important to the overall XAML story. As you start
to use controls, you will learn that those controls themselves are made
up of more primitive elements and when you want to change the way that
controls and other elements look, you will have to understand the
drawing stack.
Shapes
The most basic drawing element is a Shape.
The Shape element is a base class for a small number of shapes that are
used for basic drawing. The basic shapes are shown below:
Line
Rectangle
Ellipse
Polygon
Polyline
Path
Each of these shapes has basic attributes like Height, Width, Fill and Stroke:
<Grid>
<Rectangle Width="100"
Height="100"
Fill="Blue" />
<Ellipse Width="200"
Height="50"
Stroke="Black" />
</Grid>
If you cannot compose the kind of shape you need with the first five shapes, everything falls down to the Path shape. A Path is a powerful shape that can give you full power to design arbitrary shapes. The Path shape allows you to create open, closed or compound shapes. The Path shape has a property called Data that specifies the elements of the shape. For example, you can specify a Path with an object graph like so:
<Path Stroke="Black">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,50">
<BezierSegment Point1="50,0"
Point2="50,100"
Point3="100,50"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
By setting the Data attribute to a PathGeometry element that specifies a Path that contains a BezierSegment (from 0,50 to 100,50 with control points of 50,0 and 50,100 as the curves), you can draw a curved line as shown in Figure 1.
The Data property contains
a short-hand notation to simplify and shorten the size of the XAML.
This short hand is the same type of information, but stored in a single
string. For example, this curve can be simplified to:
<Path Stroke="Black"
Data="M 0,50 C 50,0 50,100 100,50" />
This has the same
information in it but in a shortened form. Move to the 0,50 position,
do a Bezier curve using these three points. Usually Paths are created
with tools (e.g. Expression Blend) as it can get terse but it allows
for very complex paths.
Brushes
In many of the examples so
far, you have seen colors used in the XAML to indicate different
colors. In fact those colors were a shortcut to create brushes under
the covers. Brushes are always used to paint surfaces (e.g. using Fill,
Stroke, Background). There are several types of brushes available to
you as seen in Table 1.
Table 1. Brush Types
Type | Description | Example |
---|
SolidColorBrush | Paints a solid color. | <Ellipse Fill=“Blue” /> |
LinearGraidentBrush | Paints a gradient along a line. | <Ellipse> <Ellipse.Fill> <LinearGradientBrush> <GradientStop Color=“Blue” Offset=“0” /> <GradientStop Color=“Red” Offset=“1” /> </LinearGradientBrush> </Ellipse.Fill> </Ellipse>
|
RadialGradientBrush | Paints a gradient between a focal point and a circle on the outside of the shape. | <Ellipse> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color=“Blue” Offset=“0” /> <GradientStop Color=“Red” Offset=“1” /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse>
|
ImageBrush | Paints an image. | <Ellipse> <Ellipse.Fill> <ImageBrush ImageSource=“/foo.jpg” /> </Ellipse.Fill> </Ellipse>
|
Each of the properties of a XAML element that accepts a brush object can take any of the different types of brushes.
Colors
In XAML, there are a set of built-in colors. These 141 names colors can be used to specify individual colors like so:
<Grid>
<Rectangle Fill="Blue"
Stroke="Pink" />
</Grid>
In most cases though
named colors end up being insufficient to handle the basics of colors.
Since there are millions of colors available, XAML needs a way to more
effectively specify a color. XAML supports the HTML convention of a RGB
hexadecimal string like so:
<Grid>
<Rectangle Fill="#0000FF"
Stroke="#FF0000" />
</Grid>
In this format, the pound symbol (#)
is followed by a set of hexadecimal numbers that represent the amount
of red, green and blue. Both the six and three digit formats are
supported (e.g. #FF0000 is equivalent to #F00).
In addition, XAML extends the HTML syntax to include a eight character
version. In the eight character version, the first two characters
represent a hexadecimal number that indicates the alpha channel (or
level of opaqueness):
<Grid>
<Rectangle Fill="#800000FF"
Stroke="#C0FF0000" />
</Grid>
In this example, the Fill is roughly 50% transparent and the stroke is approximately 75% opaque (or 25% transparent).
Text
For basic drawing of text, the TextBlock class is the right tool. The TextBlock
is a simple container for drawing text. It supports properties for
basic font choices like size, family, weight, foreground color,
alignment, etc.:
<Grid>
<TextBlock Text="Hello World"
Foreground="White"
FontFamily="Segoe WP"
FontSize="18"
FontWeight="Bold"
FontStyle="Italic"
TextWrapping="Wrap"
TextAlignment="Center" />
</Grid>
Along with simple text, the TextBlock class also supports simple inline formatting using the LineBreak and Run constructs:
<Grid>
<TextBlock>
Hello World. <LineBreak />This
is the second line. The breaking of
the lines in the XAML are
<Run Foreground="Red">not significant</Run>.
</TextBlock>
</Grid>
A LineBreak indicates where line breaks are going to occur without regard to the TextWrapping property. A Run is used to wrap some piece of text that needs to be formatted differently than other parts of the TextBlock. The Run supports the basic properties that a TextBlock allows but only applies them to the text inside the Run element as shown above. The TextBlock
is not a control to handle any sort of rich text or HTML-level text
handling but will suffice in most cases for text manipulation.